#include "stdafx.h"
#include "HTTPFileObject.h"
#include "IOFInternal.h"

BOOL CHttpFileObject::Open( CString sURL/*=_T("")*/
						   , CString sProxyUsername /*= _T("")*/
						   , CString sProxyPassword /*= _T("")*/
						   , CString sHttpUsername /*= _T("")*/
						   , CString sHttpPassword /*= _T("")*/ )
{
	m_sProxyUsername = sProxyUsername;
	m_sProxyPassword = sProxyPassword;
	m_sHttpUsername = sHttpUsername;
	m_sHttpPassword = sHttpPassword;
	return ParseURL(sURL);
}

void CHttpFileObject::Download(const CString &sDestFile)
{
	CTCPObject::m_ulAddress=IHTTPFile::m_ulAddress;
	CTCPObject::m_usPort=IHTTPFile::m_usPort;
	if(!sDestFile.IsEmpty())
	{
		m_sDestFile=sDestFile;
	}

	if(!OpenDestFile(!m_bContinue))
	{
		return ;
	}

	GenernateRequest();
	if(!SetSendData(m_sRequestHeader.GetBuffer(),m_sRequestHeader.GetLength()))
	{
		return ;
	}
	
	IOFrame::ioContainer()->AddObject(this);
}

BOOL CHttpFileObject::OpenDestFile(BOOL bTruncate)
{
	ASSERT(NULL==m_pDestFile);
	ASSERT(!m_sDestFile.IsEmpty());
	if(m_sDestFile.IsEmpty())
	{
		return FALSE;
	}

	try
	{
		m_pDestFile=new CFile(m_sDestFile
			,(bTruncate?0:CFile::modeNoTruncate)
			|CFile::modeCreate
			|CFile::typeBinary
			|CFile::modeWrite);
	}
	catch (CException* e)
	{
		CString sErrMsg;		
		e->GetErrorMessage(sErrMsg.GetBuffer(1001),1000);
		TRACE(sErrMsg);
		return FALSE;
	}
	m_ullDestFileSize=m_pDestFile->GetLength();
	m_ullRangeBegin=m_ullDestFileSize;
	return TRUE;
}

BOOL CHttpFileObject::OnRecvContent( LPBYTE lpBuffer,DWORD dwLen )
{
	m_ullLastBytes-=dwLen;
	m_pDestFile->Write(lpBuffer,dwLen);
	m_pMainFrame->m_ullLastBytes=m_ullLastBytes;
	if(0==m_ullLastBytes)
	{
		MessageBox(NULL,_T("OK"),NULL,MB_OK);
		m_bRetry=FALSE;
		return FALSE;
	}
	return TRUE;
}

BOOL CHttpFileObject::OnRecv( LPVOID lpBuffer,DWORD dwLen )
{
	return RecvData((LPBYTE)lpBuffer,dwLen);
}

BOOL CHttpFileObject::OnRecvHeader()
{
	CTime ctRemoteModify;
	CFileStatus fsLocalFile;
	if(_T("206")==m_sResCode
		&&GetModifyDate(ctRemoteModify)
		&&m_pDestFile->GetStatus(fsLocalFile)
		&&0!=m_ullDestFileSize)
	{
		if(fsLocalFile.m_ctime!=ctRemoteModify)
		{
			m_pDestFile->SetLength(0);
			m_bRetry=TRUE;
			m_ullDestFileSize=0;
			m_bContinue=FALSE;
			return FALSE;
		}
		else
		{
			m_pDestFile->SeekToEnd();
			m_bContinue=TRUE;
		}
	}

	if(_T("416")==m_sResCode
		&&GetModifyDate(ctRemoteModify)
		&&m_pDestFile->GetStatus(fsLocalFile)
		&&0!=m_ullDestFileSize)
	{
		if(fsLocalFile.m_ctime==ctRemoteModify)
		{
			m_bRetry=FALSE;
			return FALSE;
		}
	}

	if(_T('2')!=m_sResCode[0])
	{
		m_bRetry=FALSE;
		return FALSE;
	}
	
	if(!GetContentLength(m_ullLastBytes))
	{
		m_bRetry=FALSE;
		return FALSE;
	}
//	m_ullLastBytes-=m_ullDestFileSize;
	return TRUE;
}

void CHttpFileObject::OnError()
{
	if(NULL!=m_pDestFile)
	{
		m_pDestFile->Close();
		delete m_pDestFile;
		m_pDestFile=NULL;
		
		CFileStatus fs;
		if(CFile::GetStatus(m_sDestFile,fs)
			&&GetModifyDate(fs.m_ctime))
		{
			CFile::SetStatus(m_sDestFile,fs);
		}
	}
	
	if(m_bRetry)
	{
		m_nRetryTimes++;
		Download();
	}
}